package elastic

import (
	"context"
	"fmt"
	"gitee.com/cjf8134/bbs_serve/internal/pkg/requests"
	"gitee.com/cjf8134/bbs_serve/internal/pkg/utils/constutil"
	es "github.com/olivere/elastic/v7"
	"reflect"
)

const (
	author     = "cjf"
	project    = "bbs_serve_thread"
	mappingTpl = `	
	{
		"settings":{
			"number_of_shards":1,
			"number_of_replicas":0
		},
		"mappings":{
			"properties" : {
			  "Tag" : {
				"type" : "keyword"
			  },
			  "Username" : {
				"type" : "keyword"
			  },
			  "Avatar" : {
				"type" : "keyword"
			  },
			  "ID" : {
				"type" : "keyword"
			  },
			  "Title" : {
				"type" : "text",
				"analyzer": "ik_max_word",
		  		"search_analyzer": "ik_smart"
			  }
			}
		  }
		}
	}`
)

type ThreadEsRequest struct {
	Tag      string
	Username string
	Avatar   string
	ID       string
	Title    string
}

type ThreadES struct {
	index   string
	mapping string
	client  *es.Client
}

func NewThreadES(client *es.Client) (*ThreadES, error) {
	index := fmt.Sprintf("%s_%s", author, project)
	threadEs := &ThreadES{
		client:  client,
		index:   index,
		mapping: mappingTpl,
	}
	//创建表
	exists, err := threadEs.client.IndexExists(threadEs.index).Do(context.Background())
	if err != nil {
		return nil, err
	}
	if !exists {
		_, err := threadEs.client.CreateIndex(threadEs.index).Body(threadEs.mapping).Do(context.Background())
		if err != nil {
			return nil, err
		}
	}
	return threadEs, nil
}

//索引
func (aes *ThreadES) Index(req *ThreadEsRequest) (string, error) {
	res, err := aes.client.Index().Index(aes.index).Id(req.ID).BodyJson(req).Do(context.Background())
	if err != nil {
		return "", err
	}
	return res.Id, err
}

//得到值
func (aes *ThreadES) Search(req *requests.ThreadSearch) ([]ThreadEsRequest, error) {
	searchThreadLists := make([]ThreadEsRequest, 0)
	matchQuery := es.NewMatchQuery("Title", req.Title)
	if req.Limit <= 0 {
		req.Limit = constutil.DefaultPageSize
	}
	if req.Limit > constutil.DefaultMaxPageSize {
		req.Limit = constutil.DefaultMaxPageSize
	}
	req.Page = req.Page - 1
	if req.Page <= 0 {
		req.Page = 0
	}
	searchResult, err := aes.client.Search().
		Index(aes.index).
		Query(matchQuery).
		Sort("ID", false).
		From(req.Limit * req.Page).
		Size(req.Limit).
		Pretty(true).
		Do(context.Background())
	if err != nil {
		return nil, err
	}
	var thread ThreadEsRequest
	for _, item := range searchResult.Each(reflect.TypeOf(thread)) {
		t, ok := item.(ThreadEsRequest)
		if ok {
			searchThreadLists = append(searchThreadLists, t)
		}
	}
	return searchThreadLists, nil
}
